function SlideVerify(obj = {}, callBack = () => null) {

    SlideVerify.prototype.verifyCallBack = callBack
    SlideVerify.prototype.initDrag = initDrag

    let width = obj.width;
    let height = obj.height;
    let bgColor = obj.bgColor;
    let roundColor = obj.roundColor
    let lang = obj.lang

    // 获取dom元素

    let dragContainer = document.getElementById("dragContainer");
    let dragBg = document.getElementById("dragBg");
    let dragText = document.getElementById("dragText");
    let dragHandler = document.getElementById("dragHandler");
    let round =  dragHandler.querySelector("div");
    let maxHandlerOffset = 260;
    let isDragging = false
    let verifying = null;
    let passTimer = null;
    let verifyPortTimer = null;
    let animationChange = null;
    // 要的参数
    let pointArr = []
    let startTime = null;
    let endTime = null;
    let slideWidth = 0;
    let duration = 0

    let dragTextContent = "请按住滑块，拖动到最右边";
    let dragTextContent1 = '正在验证中'
    let dragTextContent2 = '验证通过'
    let dragTextContent3 = '验证不通过！'
    let dragTextContent4 = '数据加密失败，请联系客服！'
    let dragTextContent5 = '检测您可能为机器！，请重新刷新页面！或联系我们的客服人员！'

    let map = {}
    // 判断是否已经执行过函数
    let CarryOut = false


    const configEdit = () => {
        if (width) dragContainer.style.width = width + 'px';
        if (height) dragContainer.style.height = height + 'px';
        if (bgColor) dragBg.style.backgroundColor = bgColor;
        if (roundColor) round.style.backgroundColor = roundColor;
        if (lang === 'USD') {
            dragTextContent = 'Slide to the right';
            dragTextContent1 = 'Under verification'
            dragTextContent2 = 'Pass the verification'
            dragTextContent3 = 'Verification fails!'
            dragTextContent4 = 'Data encryption failed, please contact customer service!'
            dragTextContent5 = 'Detect what you may be for the machine! , please refresh the page! Or contact our customer service staff!'
        } else if (lang === 'HKD') {
            dragTextContent = '請按住滑塊，拖動到最右邊'
            dragTextContent1 = '正在驗證中'
            dragTextContent2 = '驗證通過'
            dragTextContent3 = '驗證不通過！'
            dragTextContent4 = '數據加密失敗，請聯繫客服！'
            dragTextContent5 = '檢測您可能為機器！，請重新刷新頁面！或聯繫我們的客服人員！'
        } else if (lang === 'RMB') {
            dragTextContent = '请按住滑块，拖动到最右边'
            dragTextContent1 = '正在验证中'
            dragTextContent2 = '验证通过'
            dragTextContent3 = '验证不通过！'
            dragTextContent4 = '数据加密失败，请联系客服！'
            dragTextContent5 = '检测您可能为机器！，请重新刷新页面！或联系我们的客服人员！'
        } else if (lang === 'VI') {
            dragTextContent = 'Vui lòng kéo sang bên phải'
            dragTextContent1 = 'đang xác nhận'
            dragTextContent2 = 'xác nhận thông qua'
            dragTextContent3 = 'xác nhận không được thông qua! '
            dragTextContent4 = 'mã hóa dữ liệu thất bại, xin vui lòng liên hệ với dịch vụ khách hàng! '
            dragTextContent5 = 'phát hiện bạn có thể là máy! Làm lại trang! Hoặc liên lạc với nhân viên dịch vụ khách hàng của chúng tôi! '
        } else if (lang === 'ES') {
            dragTextContent = 'Por favor, arrastre a la derecha'
            dragTextContent1 = 'en proceso de validación'
            dragTextContent2 = 'verificación aprobada'
            dragTextContent3 = '¡La verificación no pasó! '
            dragTextContent4 = 'el cifrado de datos falló, póngase en contacto con el servicio al cliente! '
            dragTextContent5 = 'detecta lo que puede ser para la máquina! , por favor actualice la página de nuevo! O póngase en contacto con nuestro personal de servicio al cliente! '
        }
    }

    const generateMap = () => {
        const map1 = {};
        const alphabet = 'abcdefghijklmnopqrstuvwxyz';
        const length = alphabet.length;

        for (let i = 0; i < length; i++) {
            const currentChar = alphabet[i];
            const nextChar = alphabet[(i + 1) % length]; // 循环回到 'a'
            map1[currentChar] = nextChar;
        }
        map = map1;
    }

    configEdit()
    generateMap()

    const handler = (str) => {
        let result = ''
        str.split('').forEach(char => {
            if (map[char]) {
                result += map[char]
            } else {
                result += char;
            }
        });
        return result;
    }

    function initDrag() {
        // 计算滑块的最大偏移量
        if (width)  maxHandlerOffset = width - 40;

        
        // 移除之前的事件监听器，防止重复绑定
        // mousedown
        if (window.innerWidth <= 900) {
            dragHandler.removeEventListener('touchstart', onDragHandlerMouseDown);
        } else {
            dragHandler.removeEventListener(`${handler('lntrdcnvm')}`, onDragHandlerMouseDown);
        }

        document.removeEventListener(`${handler('lntrdcnvm')}`, onDragHandlerMouseMove);
        document.removeEventListener(`${handler('lntrdto')}`, onDragHandlerMouseUp);
        document.removeEventListener(`${handler('lntrdkdzud')}`, onDragHandlerMouseUp);
        clearTimeout(verifyPortTimer)
        clearInterval(animationChange)
        clearInterval(verifying);

        animationChange = setInterval(() => {
            if (dragText.className) {
                dragText.className = ''
            } else {
                dragText.className = 'dragText'
            }
        }, 1800)

        window.addEventListener('resize',() => {
            if (window.innerWidth <= 900) {
                dragHandler.removeEventListener('touchstart', onDragHandlerMouseDown);
                dragHandler.addEventListener("touchstart", onDragHandlerMouseDown);
            } else {
                dragHandler.removeEventListener('mousedown', onDragHandlerMouseDown)
                dragHandler.addEventListener("mousedown", onDragHandlerMouseDown);
            }
        })
        dragText.textContent = dragTextContent;

        requestAnimationFrame(() => {
            if (window.innerWidth <= 900) {
                dragHandler.addEventListener("touchstart", onDragHandlerMouseDown);
            } else {
                dragHandler.addEventListener("mousedown", onDragHandlerMouseDown);
            }
            CarryOut = false;
            dragText.style.color = "";
            dragBg.style.left = 0 + 'px';
            dragBg.style.width = 0 + 'px';
            dragBg.textContent = '';
            round.className = "";
            dragHandler.className = "dragHandlerBg";
            dragHandler.style.left = 0 + 'px';
            if (dragHandler.style.cursor === 'pointer') {
                dragHandler.style.cursor = "grab";
            }
        });
    }

    const onDragHandlerMouseDown = (event) => {
        document.querySelector('body').style.userSelect = 'none';
        const now = new Date();
        startTime = now.getTime(); // 获取当前时间的 Unix 时间戳（毫秒）
        isDragging = true;
        pointArr = []
        if (window.innerWidth <= 900) {
            dragContainer.addEventListener("touchmove", onDragHandlerMouseMove, { passive: false });
        } else {
            // 鼠标移动监听
            document.addEventListener("mousemove", onDragHandlerMouseMove);
        }
        // 鼠标松开监听
        if (window.innerWidth <= 900) {
            document.addEventListener("touchend", onDragHandlerMouseUp);
        } else {
            document.addEventListener("mouseup", onDragHandlerMouseUp);
            document.addEventListener("mouseleave", onDragHandlerMouseUp);
        }
        dragHandler.style.cursor = "grabbing";

    }
    // 获取触摸事件或鼠标事件的坐标
    // 获取触摸事件或鼠标事件的坐标
    function getTouchCoordinates(event) {
        if (event.type === 'touchstart' || event.type === 'touchmove') {
            // 对于 touchstart 和 touchmove 事件，使用 event.touches
            if (event.touches && event.touches.length > 0) {
                return {
                    clientX: event.touches[0].clientX,
                    clientY: event.touches[0].clientY
                };
            }
        } else if (event.type === 'touchend' || event.type === 'touchcancel') {
            // 对于 touchend 和 touchcancel 事件，使用 event.changedTouches
            if (event.changedTouches && event.changedTouches.length > 0) {
                return {
                    clientX: event.changedTouches[0].clientX,
                    clientY: event.changedTouches[0].clientY
                };
            }
        } else {
            // 对于鼠标事件，直接使用 event.clientX 和 event.clientY
            return {
                clientX: event.clientX,
                clientY: event.clientY
            };
        }

        // 如果无法获取坐标，返回默认值
        return {
            clientX: 0,
            clientY: 0
        };
    }

    const onDragHandlerMouseMove = (event) => {
        if (!isDragging)  return;
        event.preventDefault();

        let left, top;
        if (window.innerWidth >= 900) {
            let dragX = dragContainer.getBoundingClientRect();
            left = event.clientX - dragHandler.clientWidth / 2 - dragX.left;
            top = event.offsetY
        } else {
            let dragX = dragContainer.getBoundingClientRect();
            let coords = getTouchCoordinates(event);

            left = coords.clientX - dragHandler.clientWidth / 2 - dragX.left;
            top = coords.clientY - dragHandler.clientHeight / 2 - dragX.top;
        }

        pointArr.push(`${Math.floor(Math.abs(left))},${Math.floor(Math.abs(top))}`)

        if (left < 0) {
            left = 0;
        } else if (left >= maxHandlerOffset) {
            left = maxHandlerOffset;
            dragText.textContent = ''
            verifySuccessful()
        }

        // 设置滑块位置和绿色背景宽度
        dragHandler.style.left = left + "px";
        dragBg.style.width = left + "px";
    }

    const onDragHandlerMouseUp = (event) => {
        // dragText.textContent = ''

        document.querySelector('body').style.userSelect = 'auto';
        dragHandler.style.cursor = "grab";
        let left;
        if (window.innerWidth <= 900) {
            let dragX = dragContainer.getBoundingClientRect();
            let coords = getTouchCoordinates(event);

            left = coords.clientX - dragHandler.clientWidth / 2 - dragX.left;
        } else {
            let dragX = dragContainer.getBoundingClientRect();
            left = event.clientX - dragHandler.clientWidth / 2 - dragX.left;
        }
        if (left >= maxHandlerOffset && !CarryOut) {
            verifySuccessful();
        }

        // 移除鼠标移动监听
        document.removeEventListener("mousemove", onDragHandlerMouseMove);
        // 移除鼠标松开监听
        document.removeEventListener("mouseup", onDragHandlerMouseUp);
        document.removeEventListener("mouseleave", onDragHandlerMouseUp);
        dragHandler.removeEventListener('touchstart', onDragHandlerMouseDown);

        if (isDragging) {
            Regression()
        }

    }

    function Regression () {
        const timer = setInterval(() => {
            let left = Number(dragHandler.style.left.replace("px", ""));
            if (left <= 0) {
                dragHandler.style.left = 0 + 'px';
                dragBg.style.width = 0 + 'px';
                clearInterval(timer)
                initDrag()
                return;
            }
            dragHandler.style.left = (left - 4) + 'px'
            dragBg.style.width = (left - 4) + 'px'
        })
    }

    function judgmentFn(key) {
        let pass = false
        switch (key) {
            case 'controlled':
                // 获取 User-Agent 字符串
                const userAgent = navigator.userAgent.toLowerCase();

                // 检测无头模式
                const isHeadless = /headless/.test(userAgent);
                if (isHeadless) pass = true;
                break;
        }
        return pass;
    }

    function verifySuccessful() {
        const now = new Date();
        endTime = now.getTime(); // 获取当前时间的 Unix 时间戳（毫秒）
        slideWidth = Number(dragHandler.style.left.replace("px", ""));
        duration = endTime - startTime

        isDragging = false;

        let pointText = []
        // 验证成功

        // 定义验证过程中的回调函数
        const verificationCallback = () => {
            if (pointText.length >= 3) {
                pointText = [];
            } else {
                pointText.push('.');
            }
            dragBg.textContent = `${dragTextContent1}${pointText.join('')}`;
        };

        // 立即执行一次回调函数
        verificationCallback();
        // 设置 setInterval 每隔 500 毫秒执行一次回调函数
        verifying = setInterval(verificationCallback, 500);

        dragBg.style.color = "white";

        // dragText.textContent = "验证通过";
        // dragText.style.color = "white";
        // dragHandler.className = "dragHandlerOkBg";
        // 移除鼠标按下监听
        dragHandler.removeEventListener(`${handler('lntrdcnvm')}`, onDragHandlerMouseDown);
        // 可以在这里添加额外的成功处理逻辑
        // alert('操作成功');

        verifyPortTimer = setTimeout(() => {
            verifyPort()
        })
    }


    function verifyPort() {
        CarryOut = true
        const isMachine = judgmentFn('controlled')

        if (isMachine) {
            Message(dragTextContent5, 'error')
            SlideVerify.prototype.verifyResult = Object.freeze({isPass: false})
            initDrag()
        } else {
            clearInterval(animationChange)
            SlideVerify.prototype.verifyResult = Object.freeze({isPass: true})

            const Params = handlerParams()
            // 创建 CaptchaService 实例
            const captchaService = new CaptchaService();
            // 加密
            captchaService.encrypt(Params).then(encryptedText => {

                // 创建请求体
                const requestBody = {
                    detail: encryptedText
                };

                fetch('/api/user/SlideCaptcha', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestBody),
                }).then(response => response.json())
                    .then(data => {
                        if (data && data.Error) {
                            Message(data.Error, 'error');
                            dragText.textContent = ''
                            Regression()
                            return;
                        }
                        dragHandler.style.cursor = "auto";
                        SlideVerify.prototype.verifyCallBack(data.Data.verifyCode)
                        clearInterval(verifying);
                        dragBg.textContent = dragTextContent2;
                        round.className = "dragHandlerOkBg";
                    }).catch((error) => {
                    Regression()
                    dragBg.textContent = ''
                    console.error('Error:', error);
                    Message(dragTextContent3, 'error');
                });
            }).catch(error => {
                console.error('Encryption error:', error);
                Message(dragTextContent4, 'error');
                initDrag();
            });
        }
    }


    function handlerParams() {
        const m = pointArr.map(item => {
            const arr = item.split(',');
            const x = Number(arr[0]);
            const y = Number(arr[1]);


            // 将 x 和 y 转换为十六进制，并处理负号
            const xHex = '0x' + Math.abs(x).toString(16).padStart(4, '0');
            const yHex =  Math.abs(y).toString(16).padStart(4, '0');

            // 返回拼接后的十六进制字符串
            return `${xHex}${yHex}`;
        });
        let width = Math.floor(Number(dragHandler.clientWidth) / 2)
        let height = Math.floor( Number(dragHandler.clientHeight) / 2 )

        const xWidth =   '0x' + Math.abs(width).toString(16).padStart(4, '0');
        const xHeight =   Math.abs(height).toString(16).padStart(4, '0');

        const c = `${xWidth}${xHeight}`

        const now = new Date();
        let nowDate = now.getTime()

        const st = startTime
        const et = endTime
        const d = slideWidth
        const t = Math.floor(nowDate / 1000)
        const date = new Date(nowDate)
        const t2 = date.toISOString()

        let obj = {
            m,
            st,
            et,
            d,
            c,
            t,
            t2
        }

        return JSON.stringify(obj)
    }


    let infoTimer = null;
    let sole = false;

    let Message = (info, type = '',) => {
        if (!sole) {
            sole = true
            // 创建一个新的 div 元素
            const newDiv = document.createElement('div');

            // 设置类名
            newDiv.className = 'common-info';
            newDiv.style.top = 129 + 'px'
            // 设置 div 内容


            if (type === 'error') {
                // 将 <img> 元素追加到 <div> 中
                // 创建一个新的 <img> 元素
                const img = document.createElement('div');
                img.className = 'error-wrap'
                newDiv.appendChild(img);
            }

            // 创建一个文本节点并追加到 <div> 中
            const textNode = document.createTextNode(info);
            newDiv.appendChild(textNode);

            // 将新创建的 div 添加到 body 中
            document.body.appendChild(newDiv);

            // 确保动画在添加元素后立即开始
            newDiv.style.animation = 'slideDown 1s forwards';

            // 设置定时器，在 2500 毫秒后移除元素
            infoTimer = setTimeout(() => {
                newDiv.remove();
                sole = false
            }, 2500);
        }

    }
}
function CaptchaService() {
    let map = {};
    generateMap()
    let base = handler('d226263132zc26dzb9264c26b84zb2d800d6bz5292dzbzd2652613123066bz820040z864842232d6d26526d006266b80bbd72832z2d684108908b24825228ze253z756ccaz766zc5z35d9c7ze5d9c9a75dzc5z3668c5ze6d9caz34dac9z35dbc3z34dac7za668c1ze4dzcaa35d8c9z76d9c7ze4dzc5ze6dzcaz35dzc1za66cc3z76dzc5ze6d8c1z36d8c1z7469c5za6dzc1ze46ac7z766zc1z74d8c9a35dzc5za468caza669caz346acaa746ac7z76dac4215zad5e9219c362ec77c566e6275ccb8c462db3131');

    function randomHex(length) {
        const base = '0123456789abcdef';
        let text = '';

        for (let i = 0; i < length; i++) {
            text += base.charAt(Math.floor(Math.random() * base.length));
        }

        return text;
    }

    function handler(str) {
        let result = ''
        str.split('').forEach(char => {
            if (map[char]) {
                result += map[char]
            } else {
                result += char;
            }
        });
        return result;
    }


    function generateMap() {
        let map1 = {};
        const alphabet = 'abcdefghijklmnopqrstuvwxyz';
        const length = alphabet.length;

        for (let i = 0; i < length; i++) {
            const currentChar = alphabet[i];
            const nextChar = alphabet[(i + 1) % length]; // 循环回到 'a'
            map1[currentChar] = nextChar;
        }
        map = map1;
    }

    function randomFlag() {
        const base = ['N', 'W', 'G', 'C', 'Q'];
        return base[Math.floor(Math.random() * base.length)];
    }

    function getKeySalt() {
        // 基础字符串
        const base = 'e226263132ad26eac9264d26c84ac2e800e6ca5292eacae2652613123066ca820040a864842232e6e26526e006266c80cce72832a2e684108908c24825228af253a756ddba766ad5a35e9d7af5e9d9b75ead5a3668d5af6e9dba34ebd9a35ecd3a34ebd7ab668d1af4eadbb35e8d9a76e9d7af4ead5af6eadba35ead1ab66dd3a76ead5af6e8d1a36e8d1a7469d5ab6ead1af46bd7a766ad1a74e8d9b35ead5ab468dbab669dba346bdbb746bd7a76ebd4215abe5f9219d362fd77d566f6275ddc8d462ec3131';

        // 获取最后一个字符的位置值
        const pos = parseInt(base[base.length - 1], 16);

        // 初始化 salt 数组
        const salt = [];

        for (let i = 0; i < base.length - 1; i++) {
            const char = base[i];
            const binary = parseInt(char, 16).toString(2);

            if (i === base.length - 2) {
                // 在倒数第二个字符处插入指定长度的零字符串
                salt.push('0'.repeat(pos) + binary);
            } else {
                // 其他字符转换为二进制并填充前导零
                salt.push(binary.padStart(4, '0'));
            }
        }

        return salt;
    }


    function getKey(time) {
        const salt = getKeySalt().join('');

        const blockA = [];
        const blockB = [];
        let saltOffset = 7;

        // 生成 blockA
        for (let i = 0; i < 128; i++) {
            const bin = salt.slice(saltOffset + 4 * i, saltOffset + 4 * i + 4);
            blockA.push(parseInt(bin, 2));
        }
        saltOffset += 128 * 4;

        // 生成 blockB
        for (let i = 0; i < 128; i++) {
            const bin = salt.slice(saltOffset + 7 * i, saltOffset + 7 * i + 7);
            blockB.push(String.fromCharCode(parseInt(bin, 2) - 7));
        }

        saltOffset += 128 * 7;
        const timeSeg = parseInt(time.toString().slice(-3, -1));

        let keyBase = '';

        // 遍历 128 次
        for (let i = 0; i < 128; i++) {
            const flag = salt[saltOffset + i];

            // 检查 (timeSeg >> 1) 是否在数组中
            const timeSegShifted = (timeSeg >> 1).toString();
            const inArray = ['12', '17', '21', '25', '29', '35', '33', '43', '50'].includes(timeSegShifted);

            // 根据条件选择字符
            const letter = inArray
                ? (parseInt(flag, 10) ? blockA[i] : blockB[i])
                : (parseInt(flag, 10) ? blockB[i] : blockA[i]);

            // 将选择的字符添加到 keyBase
            keyBase += letter;
        }

        // 计算偏移量
        // 计算 timeOffset
        const timeOffset = Math.abs((time - 1716789202)) % 96389;

        let key = ''

        let base = 'e00ab01775eb14f77d6bd0233e7dc74b3dd0eac1b6b347a1caf922b6d3cd5db150e6f44c14cb8ccc0d0d834b7f2da90060cb3a843320bdc2f64fd1106e6ad142726db28be01c22fddd80cacc745a65f7d9737ea530a8b0876316ddb0af397d75'

        // 计算 length
        const length = keyBase.length;

        // 计算 offset1
        const offset1 = timeOffset % length;
        // 提取 tmp
        const tmp = (time.toString()).slice(-2);

        // 计算 offset2
        let offset2 = (parseInt(tmp, 10) >> 1) % 64;

        // 循环 32 次
        for (let i = 0; i < 32; i++) {
            // 提取并转换 flag
            let flag = parseInt(base.slice(3 * offset2, 3 * offset2 + 3), 16);
            // 根据 i 的奇偶性更新 flag
            if (i % 2 === 1) {
                flag += parseInt(time.toString().slice(1), 10);
            } else {
                flag *= parseInt(time.toString().slice(5), 10);
            }

            // 计算 p
            let p = (flag % length - offset1);

            // 处理负索引
            if (p < 0) {
                p = length + p;
            }

            // 构建 key
            key += keyBase[p];

            // 更新 offset2
            offset2++;
            offset2 %= 64;
        }
        return key;
    }

    // 辅助函数
    // 加密方法
    async function encrypt(text, time = null, iv = null) {
        time = time || Math.floor(Date.now() / 1000);
        iv = iv ? base64Decode(iv) : hexToUint8Array(randomHex(32));
        const key = getKey(Math.floor(time));

        // 将 iv 转换为 WordArray
        const ivWordArray = CryptoJS.lib.WordArray.create(iv);
        const keyWordArray = CryptoJS.enc.Utf8.parse(key);
        // 加密数据
        const encrypted1 = CryptoJS.AES.encrypt(text, keyWordArray, {
            iv: ivWordArray,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
        // 获取加密后的 Base64 字符串
        const encryptedBase64 = encrypted1.toString();


        // 提取字符
        const letterA = encryptedBase64.replace(/=*$/, '').slice(-1);
        const letterB = encryptedBase64[encryptedBase64.length % 6];
        // 替换字符
        // 检查 letterA 和 letterB 是否为空
        if (letterA === '' || letterB === '') {
            throw new Error('letterA or letterB cannot be empty');
        }
        // 转义特殊字符
        const escapedLetterA = escapeRegExp(letterA);
        const escapedLetterB = escapeRegExp(letterB);

        // 替换操作
        let encrypted = encryptedBase64.replace(new RegExp(escapedLetterA, 'g'), '#');
        encrypted = encrypted.replace(new RegExp(escapedLetterB, 'g'), letterA);
        encrypted = encrypted.replace(/#/g, letterB);

        // 生成标志
        const randNum = Math.floor(Math.random() * 10);
        const lastDigitOfTime = parseInt(time.toString().slice(-1));
        const randNum2 = Math.abs(lastDigitOfTime - randNum);

        const flag = randomHex(6) + randNum + (time + 7865).toString(16) + randNum2;
        // 处理 flag 的 Base64 编码
        const reversedFlag = flag.split('').reverse().join('');
        const flagUint8Array = hexToUint8Array(reversedFlag);
        const base64EncodedFlag = uint8ArrayToBase64(flagUint8Array);

        const data1 = [
            base64EncodedFlag,
            uint8ArrayToBase64(iv),
            randomHex(3) + randomFlag() + encrypted,
        ];

        // 返回加密后的数据
        return data1.join('-');
    }

    CaptchaService.prototype.encrypt = encrypt

    function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& 表示匹配的整个子串
    }

    // 解密方法
    async function decrypt(text) {
        const [flag, iv, encrypted] = text.split('-');
        if (!flag || !iv || !encrypted) return null;

        // 解码 flag
        const flagDecoded = base64Decode(flag);
        const flagReversedHex = uint8ArrayToHex(flagDecoded).split('').reverse().join('');
        // 解码 iv
        const ivDecoded = base64Decode(iv);

        // 从 flagReversedHex 中提取时间戳
        const time = (parseInt(flagReversedHex.substring(7, 15), 16) - 7865)
        const key = getKey(time);


        // 验证时间戳和 flag 中的校验值
        const lastDigitOfTime = parseInt(time.toString().slice(-1));
        const randNum = parseInt(flagReversedHex[6]);
        const randNum2 = parseInt(flagReversedHex.slice(-1));

        if (Math.abs(lastDigitOfTime - randNum) !== randNum2) {
            return false;
        }
        // 提取并替换字符
        const letterA = encrypted.replace(/=*$/, '').slice(-1);
        const letterB = encrypted[encrypted.length % 6];

        let decrypted = encrypted.replace(new RegExp(letterA, 'g'), '#');
        decrypted = decrypted.replace(new RegExp(letterB, 'g'), letterA);
        decrypted = decrypted.replace(/#/g, letterB);

        // 去掉前缀
        decrypted = decrypted.substring(4);

        // 使用 Web Crypto API 进行解密
        const encryptedData = base64Decode(decrypted);


        const ivWordArray = CryptoJS.lib.WordArray.create(ivDecoded);

        const encryptedWordArray = CryptoJS.lib.WordArray.create(encryptedData);

        const keyWordArray = CryptoJS.enc.Hex.parse(key);
        // 解密数据
        const decrypted1 = CryptoJS.AES.decrypt(
            {
                ciphertext: encryptedWordArray
            },
            keyWordArray,
            {
                iv: ivWordArray,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            }
        );

        const decryptedText = decrypted1.toString(CryptoJS.enc.Utf8);
        return decryptedText;
    }

    CaptchaService.prototype.decrypt = decrypt

    // 十六进制字符串转换为 Uint8Array
    function hexToUint8Array(hex) {
        const len = hex.length / 2;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
            bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
        }
        return bytes;
    }

    // Uint8Array 转换为十六进制字符串
    function uint8ArrayToHex(uint8Array) {
        const hex = [];
        for (let i = 0; i < uint8Array.length; i++) {
            hex.push(uint8Array[i].toString(16).padStart(2, '0'));
        }
        return hex.join('');
    }

    // 将 Uint8Array 转换为 Base64 编码的字符串
    function uint8ArrayToBase64(uint8Array) {
        const binaryString = Array.prototype.map.call(uint8Array, (byte) => {
            return String.fromCharCode(byte);
        }).join('');
        return btoa(binaryString);
    }

    // 将 Base64 编码的字符串解码为 Uint8Array
    function base64Decode(base64) {
        const binaryString = atob(base64);
        const len = binaryString.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }
        return bytes;
    }

}




